﻿/*****************************************************************************
 * Hyldahl.Services.TaskProcessing.Test            Created by: MSH 2008.07.22
 * --------------------------------------------------------------------------
 * FileName: TaskProcessingControllerTest.cs
 * --------------------------------------------------------------------------
 * Copyright 2009 Martin Sixhøj Hyldahl
 *****************************************************************************/

using Hyldahl.Services.TaskProcessing.Configuration;
using Hyldahl.Services.TaskProcessing.Test.Dummy;
using Hyldahl.Services.TaskProcessing.Workers;
using NUnit.Framework;
using System;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;

namespace Hyldahl.Services.TaskProcessing.Test
{
    
    
    /// <summary>
    ///This is a test class for TaskProcessingControllerTest and is intended
    ///to contain all TaskProcessingControllerTest Unit Tests
    ///</summary>
    [TestFixture()]
    public class TaskProcessingControllerTest
    {
        /// <summary>
        ///A test for Workers
        ///</summary>
        [Test()]
        public void WorkersTest()
        {
            TaskProcessingController target = new TaskProcessingController(TaskProcessingApplicationContext.Current);

            Assert.IsNull(target.Workers);

            target.Initialize();

            List<Worker> actual = target.Workers;

            Assert.IsNotNull(actual);

            Assert.AreEqual(TaskProcessingServiceConfiguration.Configuration.TaskProcessingThreads.NumberOfThreads,
                            actual.Count);
        }

        /// <summary>
        ///A test for TraceSource
        ///</summary>
        [Test()]
        public void TraceSourceTest()
        {
            TaskProcessingController target = new TaskProcessingController(TaskProcessingApplicationContext.Current);

            TraceSource actual = target.TraceSource;

            Assert.IsNotNull(actual);
        }

        /// <summary>
        ///A test for Context
        ///</summary>
        [Test()]
        public void ContextTest()
        {
            TaskProcessingContext expected = TaskProcessingApplicationContext.Current;

            TaskProcessingController target = new TaskProcessingController(expected);

            TaskProcessingContext actual = target.Context;

            Assert.IsNotNull(actual);
            Assert.AreSame(expected, actual);
        }

        /// <summary>
        ///A test for ActiveWorkers
        ///</summary>
        [Test()]
        public void ActiveWorkersTest()
        {
            TaskProcessingController target = new TaskProcessingController(new DummyContext());

            target.Initialize();

            target.StartWorkers();

            // Allow the threads time to start
            Thread.Sleep(250);

            int actual = target.ActiveWorkers;

            Assert.AreEqual(TaskProcessingServiceConfiguration.Configuration.TaskProcessingThreads.NumberOfThreads,
                            actual);

            target.Dispose();
        }

        /// <summary>
        ///A test for WaitForCompletion
        ///</summary>
        [Test()]
        public void WaitForCompletionTest1()
        {
            TaskProcessingController target = new TaskProcessingController(new DummyContext(new BlockingDummyTaskDataProvider()));

            target.Initialize();
            target.StartWorkers();

            Thread.Sleep(250);

            Assert.AreEqual(TaskProcessingServiceConfiguration.Configuration.TaskProcessingThreads.NumberOfThreads,
                            target.ActiveWorkers);

            target.StopWorkers();

            TimeSpan workerTimeout = new TimeSpan(1);

            // Threads does not stop gracefully within timeout then kill the threads
            target.WaitForCompletion(workerTimeout);

            Assert.AreEqual(0, target.ActiveWorkers);
        }

        /// <summary>
        ///A test for WaitForCompletion
        ///</summary>
        [Test()]
        public void WaitForCompletionTest()
        {
            TaskProcessingController target = new TaskProcessingController(new DummyContext());

            target.Initialize();
            target.StartWorkers();

            Thread.Sleep(250);

            Assert.AreEqual(TaskProcessingServiceConfiguration.Configuration.TaskProcessingThreads.NumberOfThreads,
                            target.ActiveWorkers);

            target.StopWorkers();

            // Threads does not stop gracefully within timeout then kill the threads
            target.WaitForCompletion();

            Assert.AreEqual(0, target.ActiveWorkers);
        }

        /// <summary>
        ///A test for StopWorkers
        ///</summary>
        [Test()]
        public void StopWorkersTest()
        {
            TaskProcessingController target = new TaskProcessingController(new DummyContext(new BlockingDummyTaskDataProvider()));

            target.Initialize();
            target.StartWorkers();

            Thread.Sleep(250);

            target.StopWorkers();

            Assert.AreEqual(TaskProcessingServiceConfiguration.Configuration.TaskProcessingThreads.NumberOfThreads,
                            target.ActiveWorkers);

            target.WaitForCompletion(new TimeSpan(1));

            target.Dispose();
        }

        /// <summary>
        ///A test for StartWorkers
        ///</summary>
        [Test()]
        public void StartWorkersTest()
        {
            TaskProcessingController target = new TaskProcessingController(new DummyContext());

            target.Initialize();

            target.StartWorkers();

            // Allow the threads time to start
            Thread.Sleep(1000);

            int actual = target.ActiveWorkers;

            Assert.AreEqual(TaskProcessingServiceConfiguration.Configuration.TaskProcessingThreads.NumberOfThreads,
                            actual);

            target.Dispose();
        }

        /// <summary>
        ///A test for Initialize
        ///</summary>
        [Test()]
        public void InitializeTest()
        {
            TaskProcessingController target = new TaskProcessingController(new DummyContext());

            target.Initialize();
        }

        /// <summary>
        ///A test for Dispose
        ///</summary>
        [Test()]
        public void DisposeTest()
        {
            TaskProcessingController target = new TaskProcessingController(new DummyContext());

            target.Initialize();
            target.Dispose();
        }

        /// <summary>
        ///A test for TaskProcessingController Constructor
        ///</summary>
        [Test()]
        public void TaskProcessingControllerConstructorTest()
        {
            TaskProcessingController target = new TaskProcessingController(new DummyContext());
        }
    }
}
